{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "57ae234e-1d9a-4341-ae4b-7e2ae3da2144"
    }
   },
   "outputs": [],
   "source": [
    "# Execute this first \n",
    "#\n",
    "#  * trigger notebook styling\n",
    "#  * check if notebook had been modified since its distribution\n",
    "# \n",
    "# Note: executing any cells before this modifies the notebook.\n",
    "# \n",
    "%run src/init_notebooks.py\n",
    "hide_toggle()\n",
    "check_notebook()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "dde7b85f-ae2f-42f9-9ebf-58ab93239983"
    }
   },
   "source": [
    "# Molecular dynamics simulation of a small protein using GROMACS "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "59d19417-8116-4511-8fc5-c5abbbfe82b3"
    }
   },
   "source": [
    "    authors  : Alessandra Villa (based on a Justin Lemkuhl tutorial see http://www.mdtutorials.com or Living J. Comp. Mol. Sci. 2018, 1, 5068).    \n",
    "    goal     : learn step-by-step how to run a molecular dynamics simulation of a small protein using GROMACS \n",
    "    time     : 90 minutes\n",
    "    software : GROMACS 2022, python modules: numpy, matplotlib, re, nglviewer, md_traj, panda. \n",
    "    optional software: visualization software [VMD](https://www.ks.uiuc.edu/Research/vmd), Xmgrace plotting tool\n",
    "    tutorial source: tutorials.gromacs.org\n",
    "    version  : release"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Preparations to run this notebook"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "cf4e0e9a-6503-430f-8c60-815a9ae22616"
    }
   },
   "outputs": [],
   "source": [
    "# Change to the data directory\n",
    "# Note that executing this command twice will result in an error you can ignore\n",
    "%cd data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "3d13b2f5-7423-4201-b832-303524849db8"
    }
   },
   "source": [
    "# Obtaining the input for a simulation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "40fa54aa-811b-4991-8dcf-3fdc464b1249"
    }
   },
   "source": [
    "The starting point for each simulation is a molecular structure file. For this tutorial, we will utilize Factor Xa, a protein playing critical role in the formation of blood clots. The 3D structure is available from the RCSB website, https://www.rcsb.org/ with PDB code 1FJS. You can find the PDB file for the crystal structure in \"input\" directory as \"1fjs.pdb\"."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we visualize the structure"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import nglview as ng\n",
    "view = ng.show_structure_file(\"input/1fjs.pdb\")\n",
    "view\n",
    "# click and drag to rotate, zoom with your mouseweel \n",
    "# for more infor on this viewer have a look at https://github.com/nglviewer/nglview"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In alternative, you can use VMD to visualize the structure on your local machine. To run VMD from within this notebook, remove the comment character (#) in the following cell and VMD should pop up:\n",
    " **`close the VMD window after you are done looking at the protein to continue with this notebook`**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "c45f02d0-d499-40b4-bb12-5b54a57e2866"
    },
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "#!vmd input/1fjs.pdb"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "d5d197b7-16ea-4cb7-bc4c-dc18ea76e1d1"
    }
   },
   "source": [
    "## Cleaning the input structure"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "992503cc-771a-439b-bae3-3a660a755b7c"
    }
   },
   "source": [
    "Once you've had a look at the molecule, you are going to want to strip out all the atoms that do not belong to the protein (e.i crystal waters, ligands, etc). To delete those atoms (labelled \"HETATM\" in the PDB file) and eventually their connectivity, either use a plain text editor like vi, emacs (Linux/Mac), or Notepad (Windows). Do not use word processing software! Alternatively, you can use grep to delete these lines very easily:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "2655e386-be87-4ac5-91ef-9ac4ee9360f9"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!grep -v HETATM input/1fjs.pdb > 1fjs_protein_tmp.pdb\n",
    "!grep -v CONECT 1fjs_protein_tmp.pdb > 1fjs_protein.pdb"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "View the cleaned structure"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import nglview as ng\n",
    "view = ng.show_structure_file(\"1fjs_protein.pdb\")\n",
    "view\n",
    "# click and drag to rotate, zoom with your mouseweel \n",
    "# for more infor on this viewer have a look at https://github.com/nglviewer/nglview"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In alternative, you can use VMD to visualize the structure on your local machine. To run VMD from within this notebook, remove the comment character (#) in the following cell and VMD should pop up:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "f45c2308-0e74-4025-ac1e-200ba2869162"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "#!vmd 1fjs_protein.pdb"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "345d6e37-b392-4f54-b2ed-4d19f5c13b3d"
    }
   },
   "source": [
    "Note *Such a procedure is not universally appropriate (e.g., the case of a tightly bound ligand or otherwise functional active-site water molecule).*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "345d6e37-b392-4f54-b2ed-4d19f5c13b3d"
    }
   },
   "source": [
    "Always check your .pdb file for entries listed under the comment MISSING, as these entries indicate either atoms or whole residues that are not present in the crystal structure. Terminal regions may be absent, and may not present a problem for dynamics."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!grep MISSING input/1fjs.pdb"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "21e7a22b-6304-496d-8a9d-dfec05a513f6"
    }
   },
   "source": [
    "## Generating a topology"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "1d259e27-9071-43e4-93ab-4c45dbf7c7a1"
    }
   },
   "source": [
    "Now we have verified that all the necessary atoms are present and the PDB file contains only protein atoms, and is ready to be input into GROMACS (see <a href=http://manual.gromacs.org/current/index.html> GROMACS documentation </a>). \n",
    "The first GROMACS tool, we use, is pdb2gmx. The purpose of pdb2gmx is to generate three files:\n",
    "\n",
    "* The topology for the molecule.\n",
    "* A position restraint file.\n",
    "* A post-processed structure file. \n",
    "\n",
    "The topology (topol.top by default) contains all the information necessary to define the molecule within a simulation. This information includes nonbonded parameters (atom types and charges) as well as bonded parameters (bonds, angles, dihedrals and atom connectivity). We will take a more detailed look at the topology once it has been generated."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note *Incomplete internal sequences or any amino acid residues that have missing atoms will cause pdb2gmx to fail. These missing atoms/residues must be modeled in using other software packages. Also note that pdb2gmx is not magic. It cannot generate topologies for arbitrary molecules, just the residues defined by the force field (in the *.rtp files - generally proteins, nucleic acids, and a very finite amount of cofactors, like NAD(H) and ATP).*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Execute pdb2gmx by issuing the following command:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "2f9730de-896f-4e92-84c7-3de46d837d53"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!gmx pdb2gmx -f 1fjs_protein.pdb -o 1fjs_processed.gro -water tip3p -ff \"charmm27\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "d5ba1bb9-c859-4e03-a21b-780533486c27"
    }
   },
   "source": [
    "Here, we made an important decision for the course of the simualtion in choosing the CHARMM27 all-atom force field. The force field will contain the information that will be written to the topology. This is a very important choice! You should always read thoroughly about each force field and decide which is most applicable to your situation. Other choices are given, when running pdb2gmx without the -ff flag"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "b5b8ad6b-94b6-4ffc-b771-87dadfb78841"
    }
   },
   "source": [
    "    Select the Force Field:\n",
    "    From '/usr/local/gromacs/share/gromacs/top':\n",
    "     1: AMBER03 protein, nucleic AMBER94 (Duan et al., J. Comp. Chem. 24, 1999-2012, 2003)\n",
    "     2: AMBER94 force field (Cornell et al., JACS 117, 5179-5197, 1995)\n",
    "     3: AMBER96 protein, nucleic AMBER94 (Kollman et al., Acc. Chem. Res. 29, 461-469, 1996)\n",
    "     4: AMBER99 protein, nucleic AMBER94 (Wang et al., J. Comp. Chem. 21, 1049-1074, 2000)\n",
    "     5: AMBER99SB protein, nucleic AMBER94 (Hornak et al., Proteins 65, 712-725, 2006)\n",
    "     6: AMBER99SB-ILDN protein, nucleic AMBER94 (Lindorff-Larsen et al., Proteins 78, 1950-58, 2010)\n",
    "     7: AMBERGS force field (Garcia & Sanbonmatsu, PNAS 99, 2782-2787, 2002)\n",
    "     8: CHARMM27 all-atom force field (CHARM22 plus CMAP for proteins)\n",
    "     9: GROMOS96 43a1 force field\n",
    "    10: GROMOS96 43a2 force field (improved alkane dihedrals)\n",
    "    11: GROMOS96 45a3 force field (Schuler JCC 2001 22 1205)\n",
    "    12: GROMOS96 53a5 force field (JCC 2004 vol 25 pag 1656)\n",
    "    13: GROMOS96 53a6 force field (JCC 2004 vol 25 pag 1656)\n",
    "    14: GROMOS96 54a7 force field (Eur. Biophys. J. (2011), 40,, 843-856, DOI: 10.1007/s00249-011-0700-9)\n",
    "    15: OPLS-AA/L all-atom force field (2001 aminoacid dihedrals)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "313f7d4f-aef7-4034-a8f0-d01ccbc0f61a"
    }
   },
   "source": [
    "There are many other options that can be passed to pdb2gmx (see http://manual.gromacs.org/documentation/current/onlinehelp/gmx-pdb2gmx.html). Some commonly used ones are listed here:\n",
    "\n",
    "| Option | Effect |\n",
    "|--------|--------\n",
    "|-water  | Water model to use: none, spc, spce, tip3p, tip4p, tip5p, tips3p.|\n",
    "|-ignh   | Ignore H atoms in the PDB file; especially useful for NMR structures. Otherwise, if H atoms are present, they must be in the named exactly how the force fields in GROMACS expect them to be. Different conventions exist, so dealing with H atoms can occasionally be a headache! If you need to preserve the initial H coordinates, but renaming is required, then the Linux sed command is your friend.|\n",
    "|-ter    | Interactively assign charge states for N- and C-termini.|\n",
    "|-inter  | Interactively assign charge states for Glu, Asp, Lys, Arg, and His; choose which Cys are involved in disulfide bonds.|"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "d0e9e6a0-2330-4d50-90ee-9c2ebcfeccb9"
    }
   },
   "source": [
    "## A peek at the generated files"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "db39c2bf-2b27-4143-a5bf-2d8a9ad69a86"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!ls"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "e726db3d-da64-4dc6-979a-37de5aca3555"
    }
   },
   "source": [
    "You have now generated three new files: 1fjs_processed.gro, topol.top, topol_Protein_chain_X.itp and posre_Protein_chain_X.itp. 1fjs_processed.gro is a GROMACS-formatted structure file that contains all the atoms defined within the force field (i.e., H atoms have been added to the amino acids in the protein). The topol.top file is the system topology (more on this in a minute). The posre files contain information used to restrain the positions of heavy atoms (more on this later).\n",
    "\n",
    "One final note: many users assume that a .gro file is mandatory. This is not true. GROMACS can handle many different file formats, with .gro simply being the default for commands that write coordinate files. It is a very compact format, but it has limited precision. If you prefer to use, for instance, PDB format, all you need to do is to specify an appropriate file name with .pdb extension as your output. The purpose of pdb2gmx is to produce a force field-compliant topology; the output structure is largely a side effect of this purpose and is intended for user convenience. The format can be just about anything you like (see http://manual.gromacs.org/documentation/current/reference-manual/file-formats.html for different formats)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "aeae1bf0-ee7a-466f-8a74-ffa719813bc6"
    }
   },
   "source": [
    "# Understanding molecule \"topologies\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "93e9c7bd-075d-429f-be86-6b3118cb5b1c"
    }
   },
   "source": [
    "Let's look at what is in the output topology (topol.top). Again, using a plain text editor, inspect its contents. After several comment lines (preceded by `;`), you will find the following:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!cat topol.top"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "c2e72686-c836-46ff-947a-faaf1e87d18a"
    }
   },
   "source": [
    "The first line calls the parameters within the choosen force field. It is at the beginning of the file, indicating that all subsequent parameters are derived from this force field.  Then next important line is [ moleculetype ], that you find in  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!grep \"moleculetype\" -A 3 topol_Protein_chain_A.itp"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "and"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!grep \"moleculetype\" -A 3 topol_Protein_chain_L.itp"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "49a884b4-6326-4c0b-99a0-d66f60bd9e4d"
    }
   },
   "source": [
    "The name \"Protein_chain_A\" defines the molecule name, based on the fact that the protein was labeled as chain A in the PDB file. There are 3 exclusions for bonded neighbors. More information on exclusions can be found in the <a href=http://manual.gromacs.org/current/reference-manual/topologies.html>GROMACS manual</a>."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "db680c9f-9999-4423-b607-47b2746a64c4"
    }
   },
   "source": [
    "## Atoms in a topology"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "98122e18-61f8-44b2-b5cf-6b4fa20ae864"
    }
   },
   "source": [
    "The next section defines the [ atoms ] in the protein. The information is presented as columns:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "! grep \"atoms\" -A 4 topol_Protein_chain_A.itp"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "09648857-440c-4e54-86c6-932fa288cfa9"
    }
   },
   "source": [
    "The interpretation of this information is as follows:\n",
    "\n",
    "|Field  |  description |\n",
    "|--|--\n",
    "|nr|Atom number\n",
    "|type| Atom type\n",
    "|resnr|Amino acid residue number\n",
    "|residue| The amino acid residue name- Note that this may be different from .rtp entry. \n",
    "|atom| Atom name\n",
    "|cgnr| Charge group number - Not used anymore \n",
    "|charge| Self-explanatory - The \"qtot\" descriptor is a running total of the charge on the molecule\n",
    "|mass| Also self-explanatory\n",
    "|typeB, chargeB, massB| Used for free energy perturbation (not discussed here) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "18a65484-38e3-49fc-9dc2-57f04d698628"
    }
   },
   "source": [
    "## Bonds and other interactions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "0a8bda1d-2727-4a76-983d-dab8112e1dcf"
    }
   },
   "source": [
    "Subsequent sections include [ bonds ], [ pairs ], [ angles ], and [ dihedrals ]. Some of these sections are self-explanatory (bonds, angles, and dihedrals). These interactions are found [here](http://manual.gromacs.org/current/reference-manual/functions.html) and special 1-4 interactions are included under [pairs](http://manual.gromacs.org/current/reference-manual/functions/interaction-methods.html#exclusions-and-1-4-interactions). For format associated to function types [see topology file table](http://manual.gromacs.org/documentation/2020-beta1/reference-manual/topologies/topology-file-formats.html) in GROMACS manual."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below we look for these interactions in topolology file. As example we start with chain A. Bonded interactions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!grep \"bonds\" -A 2 topol_Protein_chain_A.itp"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pair interactions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!grep \"pairs\" -A 2  topol_Protein_chain_A.itp"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Angle interactions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!grep \"angles\" -A 2 topol_Protein_chain_A.itp"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Dihedral interactions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!grep \"dihedrals\" -A 2 topol_Protein_chain_A.itp"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "ef42771f-cf92-4505-a904-9e5b8f9ab0d1"
    }
   },
   "source": [
    "## Water and position restraints"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "b43f5e17-887e-415c-a7da-1b61d8e53b93"
    }
   },
   "source": [
    "The remainder of the file involves including a few other useful/necessary topologies, starting with position restraints. The \"posre.itp\" file was generated by pdb2gmx; it defines a force constant used to keep atoms in place during equilibration (more on this later)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!grep \"posre\" topol*.itp"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "04e0801a-6444-4279-b4ed-36245a918cba"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!cat posre_Protein_chain_A.itp"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "3efdb33e-1797-47b0-8866-deb26bef0b7b"
    }
   },
   "source": [
    "Here ends the \"Protein_chain_A\" moleculetype definition. Then the \"Protein_chain_L\" moleculetype definition starts. The remainder of the topology file is dedicated to defining other molecules and providing system-level descriptions. The next moleculetype (by default) is the solvent, in this case TIP3P water. Other typical choices for water include SPC, SPC/E, and TIP4P. We chose this by passing \"-water tip3p\" to pdb2gmx. For an excellent summary of the many different water models, click [here](http://www1.lsbu.ac.uk/water/water_models.html) , but be aware that not all of these models are present within GROMACS."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "39ea31e7-3219-49d9-b756-2bd0fb8dca0b"
    }
   },
   "source": [
    "## Ions and other parameters"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "ecd3d9b7-4388-4f41-a597-677407b6a8fd"
    }
   },
   "source": [
    "Ion parameters are included next:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!grep \"ions\" topol.top"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## System level definitions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "5ccbb2b2-116b-48d2-9212-33ff648831ca"
    }
   },
   "source": [
    "Finally come system-level definitions. The [ system ] directive gives the name of the system that will be written to output files during the simulation. The [ molecules ] directive lists all of the molecules in the system."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!tail -8 topol.top"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "8c2b434c-5817-4179-9529-ec89fdb0800d"
    }
   },
   "source": [
    "A few key notes about the `[ molecules ]` directive:\n",
    "\n",
    "- The order of the listed molecules must exactly match the order of the molecules in the coordinate (in this case, .gro) file.\n",
    "- The names listed must match the `[ moleculetype ]` name for each species, not residue names or anything else.\n",
    "\n",
    "If you fail to satisfy these concrete requirements at any time, you will get fatal errors from grompp (discussed later) about mismatched names, molecules not being found, or a number of others."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "3b32f9b6-e20b-460f-ae55-7cdd99ea1892"
    }
   },
   "source": [
    "Now that we have examined the contents of a topology file, we can continue building our system."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "598b0d30-9d4c-4b31-a670-959bb96ab87f"
    }
   },
   "source": [
    "# Solvating the simulation system"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "4c7344d8-d42d-4e4c-918c-0e1a160a1319"
    }
   },
   "source": [
    "Now that you are familiar with the contents of the GROMACS topology, it is time to continue building our system. In this example, we are going to be simulating a simple aqueous system. It is possible to simulate proteins and other molecules in different solvents, provided that good parameters are available for all species involved.\n",
    "\n",
    "There are two steps to defining the box and filling it with solvent:\n",
    "\n",
    "- Define the box dimensions using the editconf module.\n",
    "- Fill the box with water using the solvate module. \n",
    "\n",
    "You are now presented with a choice as to how to treat the unit cell. For the purpose of this tutorial, we will use the rhombic dodecahedron, as its volume is ~71% of the cubic box of the same periodic distance, thus saving on the number of water molecules that need to be added to solvate the protein."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "95ad5707-817d-46aa-b35f-09cfb6796c02"
    }
   },
   "source": [
    "## Defining the simulation box"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "b6a06a69-5b82-4302-a61f-ba3c568c497e"
    }
   },
   "source": [
    "Let's define the box using editconf:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "23d642d0-a609-4be8-aed1-00aee72b22bf"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!gmx editconf -f 1fjs_processed.gro -o 1fjs_newbox.gro -c -d 1.0 -bt dodecahedron"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "e68f5978-ef1b-4700-84bb-a40173c8ccf8"
    }
   },
   "source": [
    "The above command centers the protein in the box (-c), and places it at least 1.0 nm from the box edge (-d 1.0). The box type is defined as a rhombic dodecahedron (-bt dodecahedron). Have a look at this [section](http://manual.gromacs.org/current/reference-manual/algorithms/periodic-boundary-conditions.html#pbc) in the manual for more on periodic boundary conditions and dodecahedrons."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "e68f5978-ef1b-4700-84bb-a40173c8ccf8"
    }
   },
   "source": [
    "The distance to the edge of the box is an important parameter. A protein should never interact with its periodic image (minimum image convention), otherwise the forces calculated will be spurious. The minimum image convention implies that the distance between two periodic images of the protein should be larger than the cut-off radius used to truncate non-bonded interactions. Here we will use a cut-off radius of 1.2 nm (see below). Specifying a solute-box distance of 1.0 nm will mean that there are at least 2.0 nm between any two periodic images of a protein. We expect that at that distance all protein-protein interactions are negligble."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "75d89a8d-1463-4767-a002-581b3c015753"
    }
   },
   "source": [
    "## Filling the box with water"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "82f1ad5a-cef0-46fe-9494-92477b273cd9"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!gmx solvate -cp 1fjs_newbox.gro -cs spc216.gro -o 1fjs_solv.gro -p topol.top"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "3fb8e6fc-1343-47e9-925c-c754b822b91b"
    }
   },
   "source": [
    "The configuration of the protein (-cp) is contained in the output of the previous editconf step, and the configuration of the solvent (-cs) is part of the standard GROMACS installation. We are using spc216.gro, which is a generic equilibrated 3-point solvent model box. You can use spc216.gro as the solvent configuration for SPC, SPC/E, or TIP3P water, since they are all three-point water models. The output is called 1fjs_solv.gro, and we tell solvate the name of the topology file (topol.top) so it can be modified. Note the changes to the [ molecules ] directive of topol.top:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "27850d11-a3ed-4feb-939a-3d687b5ab001"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!tail topol.top"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "cf8c6e22-eb31-486d-88d9-67d800524670"
    }
   },
   "source": [
    "\n",
    "`gmx solvate` kept track of how many water molecules it has added, which it then writes to your topology to reflect the changes that have been made. Note that if you use any other (non-water) solvent, solvate will not make these changes to your topology! Its compatibility with updating water molecules is hard-coded."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "33086651-f3c8-43b7-b47f-36645fa72aaa"
    }
   },
   "source": [
    "# Adding Ions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "1c524b7e-8fcc-420a-b0fb-8ccb7d0f54c1"
    }
   },
   "source": [
    "We now have a solvated system that contains a charged protein. The output of `pdb2gmx` told us that the protein has a net charge of -2e (based on its amino acid composition). If you missed this information in the `pdb2gmx` output, look at the last line of each [ atoms ] directive in topology file; it should read  \"qtot 1.\" for chain A and  \"qtot -3.\" for chain L. Since life does not exist at a net charge, we must add ions to our system. Further, we aim to approximate physiological conditions and use therefore a NaCl concentration of 0.15 M."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "3c3ff084-1058-4bf3-afa0-a0cea3c1df09"
    }
   },
   "source": [
    "## Preparing the input for \"gmx genion\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "68bf2221-bfce-429a-95d9-156af62a3359"
    }
   },
   "source": [
    "The tool for adding ions within GROMACS is called `genion`. What genion does is read through the topology and replace water molecules with the ions that the user specifies. The input is called a run input file, which has an extension of .tpr; this file is produced by the GROMACS grompp module (GROMACS pre-processor), which will also be used later when we run our first simulation. `grompp` processes the coordinate file and topology (which describes the molecules) to generate an atomic-level input (`.tpr`). The .tpr file contains all the parameters for all of the atoms in the system."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "15158eb8-2025-44e7-88dd-9966aea64b60"
    }
   },
   "source": [
    "To produce a .tpr file with grompp, we will need an additional input file, with the extension .mdp (molecular dynamics parameter file); grompp will assemble the parameters specified in the .mdp file with the coordinates and topology information to generate a .tpr file."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "cc071b1a-1700-4426-9285-a039f320ee60"
    }
   },
   "source": [
    "An .mdp file is normally used to run energy minimization or an MD simulation, but in this case is simply used to generate an atomic description of the system. We can proceed with an completely empty .mdp file in this case, its only role is to create the .tpr file."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!touch ions.mdp"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "3f058b29-44cc-4e0c-8462-588b1279457b"
    }
   },
   "source": [
    "Assemble your .tpr file with the following:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "1bc074e1-d521-46ec-b9a2-359cdea24637"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!gmx grompp -f ions.mdp -c 1fjs_solv.gro -p topol.top -o ions.tpr"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "9c28bff3-bef7-4d81-aac3-7581c40629c2"
    }
   },
   "source": [
    "Be aware that there are some `NOTE` in the output. In all other cases than generating an output `tpr` for `genion` these are very important and may not be ignored, here however we only need the atomic-level description of our system in the binary file ions.tpr. We will pass this file to genion:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Note: A lot of GROMACS tools promt for input at the command line. As this does not play well with the jupyter notebook setup, we feed the input to the command line with a print command and a newline \\n substituting enter*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "88837846-7a76-4ce4-9419-6588a42e8b1f"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!printf \"SOL\\n\" | gmx genion -s ions.tpr -o 1fjs_solv_ions.gro -conc 0.15 -p \\\n",
    "topol.top -pname NA -nname CL -neutral"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "af2e805e-ca9f-4b95-b58f-0d4055f7d165"
    }
   },
   "source": [
    "We chose group \"SOL\" for embedding ions. You do not want to replace parts of your protein with ions."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Note: Make sure to run genion only once. `gmx genion` edits the topology \"in-place\" and does not know if there are already Cl or Na ions in the system. If you run it over again, ions will be added until there is no water left to replace with ions.*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "9f3bfe12-f048-4d58-88ed-b2cb22450ea2"
    }
   },
   "source": [
    "In the genion command, we provide the structure/state file (-s) as input, generate a .gro file as output (-o), process the topology (-p) to reflect the removal of water molecules and addition of ions, define positive and negative ion names (-pname and -nname, respectively), and tell genion to add ions necessary to neutralize the net charge on the protein by adding the correct number of negative ions (-neutral, which in this case will add 2 Na+ ions to offset the -2 charge on the protein). We further use genion to add a specified concentration of ions in addition to simply neutralizing the system by specifying the -neutral and -conc options in conjunction. Refer to the genion man page for information on how to use these options.\n",
    "\n",
    "The names of the ions specified with -pname and -nname GROMACS are standardized and not dependent on the force-field. The specified ion names are always the elemental symbol in all capital letters, which is the [ moleculetype ] name that is then written to the topology. Residue or atom names may or may not append the sign of the charge (+/-), depending on the force field. Do not use atom or residue names in the genion command, or you will encounter errors in subsequent steps."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "e474e9aa-baeb-4ff7-b445-c17bbdd0173a"
    }
   },
   "source": [
    "Your [ molecules ] directive should now be similar to"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "3fe444f7-f9a1-4b1b-8faa-8436793520fe"
    }
   },
   "source": [
    "    [ molecules ]\n",
    "    ; Compound      #mols\n",
    "    Protein_chain_A    1\n",
    "    Protein_chain_L    1\n",
    "    SOL           11703\n",
    "    NA              38\n",
    "    CL              36"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's check the last lines of the topology file"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "e6be30a5-ee4c-44f9-bb44-5799f3e70317"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!tail -6 topol.top"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you see multiple lines of NA and CL, you most likely ran genion multiple times. Start over with the `pdb2gmx`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "bb96f417-4653-4a5e-914c-54771fe98290"
    }
   },
   "source": [
    "# Energy minimisation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "60af9d49-7607-43dd-b50e-ed6111b93c45"
    }
   },
   "source": [
    "The solvated, electroneutral system is now assembled. Before we can begin dynamics, we must ensure that the system has no steric clashes or inappropriate geometry. The structure is relaxed through a process called energy minimization (EM)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "60af9d49-7607-43dd-b50e-ed6111b93c45"
    }
   },
   "source": [
    "To perform energy minimization, we are once again going to use grompp to assemble the structure, topology, and simulation parameters into a binary input file (.tpr), then we will use GROMACS MD engine, mdrun, to run the energy minimization."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "60af9d49-7607-43dd-b50e-ed6111b93c45"
    }
   },
   "source": [
    "Assemble the binary input using grompp using the .mdp parameter file, as input. The simulation parameter file (.mdp) determines how the simulation shall be run. Find more information on all the options in the [manual](http://manual.gromacs.org/documentation/current/user-guide/mdp-options.html) or in the following [webinar](https://bioexcel.eu/webinar-a-walk-through-simulation-parameter-options-mdp-files-for-gromacs-2019-12-05/). There are a lot of parameters that can be set, here we ony set the elemental parametes and leave everything else as default. Let's have a look at the input file:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!cat input/emin-charmm.mdp"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "34b6c3cb-5926-4ba5-b97a-8b42457956ce"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!gmx grompp -f input/emin-charmm.mdp -c 1fjs_solv_ions.gro -p topol.top -o em.tpr"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "b59bc1fe-5773-440c-ac9e-109d3df55ec4"
    }
   },
   "source": [
    "Make sure you have been updating your topol.top file when running genbox and genion, or else you will get lots of nasty error messages (\"number of coordinates in coordinate file does not match topology,\" etc)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "a9136c8d-2907-40aa-9eae-d697c9467e49"
    }
   },
   "source": [
    "Once run, we will find the energy-minimized structure in a file called `em.gro`. Additionally to this we will find more information on the run in an ASCII-text log file of the EM process,  `em.log`, a file for storage of energy, `em.edr` and a binary full-precision trajectory `em.trr`. \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "b59bc1fe-5773-440c-ac9e-109d3df55ec4"
    }
   },
   "source": [
    "We are now ready to run mdrun to carry out the energy minimisation:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "eb3e7e13-d78e-4c99-806c-99e9b30d3d69"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!gmx mdrun -v -deffnm em"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "65593f21-7e6d-426e-a48e-847cd9faa631"
    }
   },
   "source": [
    "The -v flag is for the impatient: it makes mdrun verbose, such that it prints its progress to the screen at every step. Never use this flag if run in background, on a HPC center or on a local cluster, it prints unnecessary data in the standard output file. \n",
    "The -deffnm flag will define the file names of the input and output. So, if you did not name your grompp output \"em.tpr,\" you will have to explicitly specify its name with the mdrun -s flag."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Note: if you do not want to wait, but look at some of the results directly, copy the data from the /reference directory into the current directory. To do this from within this notebook, remove the comment characters (#) in the following cell*  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "## ONLY execute the lines below if you do not want to run and wait for the simulation to finish\n",
    "#!cp reference/em_charmm.edr em.edr\n",
    "#!cp reference/em_charmm.gro em.gro"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "0274fdde-8eaf-4df7-b0da-f7744035566f"
    }
   },
   "source": [
    "## Determining if the run was successful"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "a1ca837f-1179-4518-a425-cd9ad733cd73"
    }
   },
   "source": [
    "There are two very important factors to evaluate to determine if EM was successful. \n",
    "\n",
    "The first is the potential energy (printed at the end of the EM process, even without -v). Epot should be negative and (for a simple protein in water) on the order of 100000 kJ/mol, depending on the system size and number of water molecules\n",
    "\n",
    "The second important feature is the maximum force, Fmax, the target for which was set in minim.mdp - \"emtol = 1000.0\" - indicating a target Fmax of no greater than 1000 kJ/(mol nm). It is possible to arrive at a reasonable Epot with Fmax > emtol. If this happens, your system may not be stable enough for simulation. Evaluate why it may be happening, and perhaps change your minimization parameters (integrator, emstep, etc).\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "08ee3d6c-ad7d-42be-9622-f43d9ab3d1e7"
    }
   },
   "source": [
    "## Analysing the run results"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "e4c99f39-4127-487f-b3fe-fbe5b3595316"
    }
   },
   "source": [
    "Let's do a bit of analysis. The em.edr file contains all of the energy terms that GROMACS collects during EM. You can analyze any .edr file using the GROMACS energy module:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "4c87141e-8583-497a-8c8c-22ca7e149a3f"
    }
   },
   "source": [
    "To analyse or visualize simulation data in python or jupyter notebooks, we can output a simplified xvg format from gmx-analysis tools with the option `-xvg none`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "9ebad872-0589-4675-a240-b89c396a35c1"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!printf \"Potential\\n0\\n\" | gmx energy -f em.edr -o potential.xvg -xvg none"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "a4591650-99ca-436f-a572-7e254adb454e"
    }
   },
   "source": [
    "You will be shown the average of Epot, and a file called \"potential.xvg\" will be written. To plot this data file, you can use the script below. The resulting plot should show a steady convergence of Epot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "4ce04079-a188-4372-ac3f-10665cd8b1a5"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "df = pd.read_csv('potential.xvg', sep='\\s+', header=None, names=['time','energy'])\n",
    "df.plot('time')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "ca79195b-10c4-4c90-8d1c-b4706aeba797"
    }
   },
   "source": [
    "In alternative you can plot data file using Xmgrace plotting tool by directly output xvg format from the analysis tools. To use xmgrace from this notebook, remove the comment character (#) in the following cells: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "1b4235fe-77e5-4874-8519-aaacde0dcacb"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "#!printf \"Potential\\n0\\n\" | gmx energy -f em.edr -o potential.xvg"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "ca79195b-10c4-4c90-8d1c-b4706aeba797"
    }
   },
   "source": [
    "To plot this data file, now you will need the Xmgrace plotting tool. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "ecd1a98a-daa7-4f2e-9825-824bee8578ad"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "#!xmgrace potential.xvg"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "e6db598c-b3ac-4a16-8044-1662a0646b15"
    }
   },
   "source": [
    "Now that our system is at an energy minimum, we can begin real dynamics."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "4c85e968-f181-42fb-a3b3-ab42facdb15a"
    }
   },
   "source": [
    "# Position restraints "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "2b10cf65-f4fd-4244-bb0b-612e4aa3ade8"
    }
   },
   "source": [
    "EM ensured that we have a reasonable starting structure, in terms of geometry and solvent orientation. To begin real dynamics, we must equilibrate the solvent and ions around the protein. If we were to attempt unrestrained dynamics at this point, the system may collapse. The reason is that the solvent is mostly optimized within itself, and not necessarily with the solute, and ions are randomly placed by replacing water molecules."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "2b10cf65-f4fd-4244-bb0b-612e4aa3ade8"
    }
   },
   "source": [
    "Remember that posre.itp file that pdb2gmx generated a long time ago? We're going to use it now. The purpose of posre.itp is to apply a position restraining force on the heavy atoms of the protein (anything that is not a hydrogen). Movement is permitted, but only after overcoming a substantial energy penalty. The utility of position restraints is that they allow us to relax our solvent and ions around our protein, without the added variable of structural changes in the protein. The origin of the position restraints (the coordinates at which the restraint potential is zero) is provided via a coordinate file passed to the -r option of grompp. Depending from the protein and ion types, this process may also be in the order nanoseconds."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "2b10cf65-f4fd-4244-bb0b-612e4aa3ade8"
    }
   },
   "source": [
    "To use position restraints we need to add \\\"define = -DPOSRES\\\" to the simulation parameter file, .mdp, (more details on the simulation parameters below). Have a look at the .mdp file for this run:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!head -5 input/nvt-charmm.mdp "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When using position restraints, a file with restraint coordinates must be supplied with -r to gmx grompp (see below). It can be the same file as supplied for -c. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "4c85e968-f181-42fb-a3b3-ab42facdb15a"
    }
   },
   "source": [
    "# Equilibration run - temperature"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "2b10cf65-f4fd-4244-bb0b-612e4aa3ade8"
    }
   },
   "source": [
    "EM ensured that we have a reasonable starting structure, in terms of geometry and solvent orientation. Now the system needs to be brought to the temperature we wish to simulate and establish the proper orientation about the solute (the protein). After we arrive at the correct temperature (based on kinetic energies), we will apply pressure to the system until it reaches the proper density."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "2b10cf65-f4fd-4244-bb0b-612e4aa3ade8"
    }
   },
   "source": [
    "Equilibration is often conducted in two phases. The first phase is conducted under an NVT ensemble (constant Number of particles, Volume, and Temperature). This ensemble is also referred to as \"isothermal-isochoric\" or \"canonical.\" The timeframe for such a procedure is dependent upon the contents of the system. Typically, 100-200 ps should suffice, and we will conduct a 100-ps NVT equilibration for this exercise. Depending on your machine, this may take a while (just under an hour if run in parallel on 16 cores or so)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "2b10cf65-f4fd-4244-bb0b-612e4aa3ade8"
    }
   },
   "source": [
    "We will call grompp and mdrun just as we did at the EM step, but this time with the energy minimised structure as input and a different .mdp file for the run. Have a look at the input file for this run:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!cat input/nvt-charmm.mdp"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "cc6aa785-2b71-44bc-8a86-0c95e3b65c82"
    }
   },
   "source": [
    "Instead of energy tolerance, we now give time a step size and a number of steps. Furthermore, we need to set a temperature. Now, we're good to run. Take note of a few parameters in the .mdp file:\n",
    "\n",
    "- `gen_vel = yes`: Initiates velocity generation. Using different random seeds (gen_seed) gives different initial velocities, and thus multiple (different) simulations can be conducted from the same starting structure.\n",
    "- `tcoupl = V-rescale`: The velocity rescaling thermostat is an improvement upon the Berendsen weak coupling method, which did not reproduce a correct kinetic ensemble.\n",
    "- `pcoupl = no`: Pressure coupling is not applied. \n",
    "\n",
    "A full explanation of the parameters used can be found in the GROMACS [manual](http://manual.gromacs.org/documentation/current/user-guide/mdp-options.html), in addition to the comments provided. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, we're good to run."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "2b413eeb-b4a1-4499-b977-156c6a0b4566"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!gmx grompp -f input/nvt-charmm.mdp -c em.gro -r em.gro -p topol.top -o nvt.tpr \n",
    "!gmx mdrun -ntmpi 1 -v -deffnm nvt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "828a3d07-e09e-44a3-8c97-350bb3a42a84"
    }
   },
   "source": [
    "Your computer should be working at full speed now to finish this simulation; it should be done in 5 to 10 minutes. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Note: if you do not want to wait, but look at some of the results directly, copy the data from the /reference directory into the current directory. To do this from within this notebook, remove the comment characters (#) in the following cell*  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "## ONLY execute the lines below if you do not want to run and wait for the simulation to finish\n",
    "#!cp reference/nvt_charmm.edr nvt.edr\n",
    "#!cp reference/nvt_charmm.gro nvt.gro\n",
    "#!cp reference/nvt_charmm.cpt nvt.cpt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "cc6aa785-2b71-44bc-8a86-0c95e3b65c82"
    }
   },
   "source": [
    "Let's analyze the temperature progression, again using gmx energy:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "a414818c-cb67-4514-a983-5322d9d388b0"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!echo \"Temperature\" | gmx energy -f nvt.edr -o temperature.xvg -xvg none"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "4ce04079-a188-4372-ac3f-10665cd8b1a5"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "df = pd.read_csv('temperature.xvg', sep='\\s+', header=None, names=['time','temperature'])\n",
    "df.plot('time')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Or for alterantive visualization, remove the comment characters (#) in the following cells:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "a414818c-cb67-4514-a983-5322d9d388b0"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "#!echo \"Temperature\" | gmx energy -f nvt.edr -o temperature.xvg"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "e44de384-42ac-4813-9a45-cc496b28a4d7"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "#!xmgrace temperature.xvg"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "00806afa-b604-4964-9616-edc3ff3d046d"
    }
   },
   "source": [
    "From the plot, it is clear that the temperature of the system quickly reaches the target value (300 K), and remains stable over the remainder of the equilibration. For this system, an equilibration period (on the order of 50 ps) may be adequate."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "82f60247-efd9-4559-9b40-ddc31d78b0cf"
    }
   },
   "source": [
    "# Equilibration run - pressure"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "d420cdd6-a94d-49a4-8776-c5ceee7b3cb4"
    }
   },
   "source": [
    "The previous step, NVT equilibration, stabilized the temperature of the system. Prior to data collection, we must also stabilize the pressure (and thus also the density) of the system. Equilibration of pressure is conducted under an NPT ensemble, wherein the Number of particles, Pressure, and Temperature are all constant. The ensemble is also called the \"isothermal-isobaric\" ensemble, and most closely resembles experimental conditions.\n",
    "\n",
    "The .mdp file used for a 100-ps NPT equilibration can be found here. It is not drastically different from the parameter file used for NVT equilibration. Note the addition of the pressure coupling section. Berendsen barostat is used for this equilibation phase."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!cat input/npt-charmm.mdp"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "d420cdd6-a94d-49a4-8776-c5ceee7b3cb4"
    }
   },
   "source": [
    "A few other changes:\n",
    "\n",
    "- `continuation = yes`: We are continuing the simulation from the NVT equilibration phase\n",
    "- `gen_vel = no`: Velocities are read from the trajectory (see below) \n",
    "\n",
    "We will call grompp and mdrun just as we did for NVT equilibration. Note that we are now including the -t flag to include the checkpoint file from the NVT equilibration; this file contains all the necessary state variables to continue our simulation. To conserve the velocities produced during NVT, we must include the final coordinate file (output) of the NVT simulation using the option (-c)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "d0031438-f9e0-4d31-9c19-df4dc92d2d22"
    }
   },
   "outputs": [],
   "source": [
    "!gmx grompp -f input/npt-charmm.mdp -c nvt.gro -r nvt.gro -t nvt.cpt -p topol.top -o npt.tpr"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "6fd8fd4f-6972-4eed-91c9-805282079174"
    }
   },
   "source": [
    "Now we'll start an MD simulation just like before - this one will take a few minutes; that's why it is commented out. Go ahead run it if you want to generate your own data.   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "8a3208e1-acc3-40ab-b3be-a26fa2bb071c"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!gmx mdrun -ntmpi 1 -v -deffnm npt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "d0acf72c-7b94-4864-89a4-84674b63a04e"
    }
   },
   "source": [
    "If the simulation takes too long to run for this tutorial, you may use the provided data by copying it to the current directory. But remember that you can always check/analyse the output files while the simulation is still running. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "cefe08a1-7c2d-4d1d-a575-50a07b1254d8"
    }
   },
   "outputs": [],
   "source": [
    "##ONLY execute the lines below if you do not want to run and wait for the simulation to finish\n",
    "#!cp reference/npt_charmm.edr npt.edr\n",
    "#!cp reference/npt_charmm.gro npt.gro\n",
    "#!cp reference/npt_charmm.cpt npt.cpt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "eb120f75-b472-4cb1-a3ee-21c580ca03e7"
    }
   },
   "source": [
    "Let's analyze the pressure progression, again using energy:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "dd41db3e-bcdb-4cad-a8c7-834ebd3b6078"
    },
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "!echo \"Pressure\" | gmx energy -f npt.edr -o pressure.xvg -xvg none"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "4ce04079-a188-4372-ac3f-10665cd8b1a5"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "df = pd.read_csv('pressure.xvg', sep='\\s+', header=None, names=['time','pressure'])\n",
    "df.plot('time')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Or for alterantive visualization, remove the comment characters (#) in the following cells:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "a414818c-cb67-4514-a983-5322d9d388b0"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "#!echo \"Pressure\" | gmx energy -f npt.edr -o pressure.xvg"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "c1fd41ec-970c-46aa-abf9-23954d3eb887"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "#!xmgrace pressure.xvg"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "24293621-f825-48bb-8493-b42fbc65c616"
    }
   },
   "source": [
    "The pressure value fluctuates widely over the course of the 100-ps equilibration phase, but this behavior is not unexpected. The reference pressure was set to 1 bar, so is this outcome acceptable? Pressure is a quantity that fluctuates widely over the course of an MD simulation, as is clear from the large root-mean-square fluctuation (in the order of 100 bar), so statistically speaking, one cannot distinguish a difference between the obtained average and the target/reference value (1 bar). \n",
    "\n",
    "Let's take a look at density as well using energy."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "5f5636cc-2d8e-4fcb-b1a3-a6aa5e059be9"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!echo \"Density\" | gmx energy -f npt.edr -o density.xvg -xvg none"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "4ce04079-a188-4372-ac3f-10665cd8b1a5"
    },
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "df = pd.read_csv('density.xvg', sep='\\s+', header=None, names=['time','density'])\n",
    "df.plot('time')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Or for alterantive visualization, remove the comment characters (#) in the following cells:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "a414818c-cb67-4514-a983-5322d9d388b0"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "#!echo \"Density\" | gmx energy -f npt.edr -o density.xvg"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "1b457711-eabc-471c-adff-b44c56fefca1"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "#!xmgrace density.xvg"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "55be45c5-3caa-472d-995e-9e9532ff4f86"
    }
   },
   "source": [
    "The average value is close to the experimental value of 1000 kg m-3 and the expected density of the TIP3P model of 1001 kg m-3. The parameters for the TIP3P water model closely replicate experimental values for water. The density values are very stable over time, indicating that the system is well-equilibrated now with respect to pressure and density.\n",
    "\n",
    "Please note: Pressure-related terms are slow to converge, and thus you may have to run NPT equilibration slightly longer than is specified here."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "bcefd2f6-8318-40a7-98e0-dc89ecb9ca56"
    }
   },
   "source": [
    "# The \"production\" run"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "f366f0c1-5bb1-47a1-a8af-e6f79e7eb2fc"
    }
   },
   "source": [
    "Upon completion of the two equilibration phases, the system is now well-equilibrated at the desired temperature and pressure. We are now ready to release the position restraints and run production MD for data collection. The process is just like we have seen before, as we will make use of the checkpoint file (which in this case now contains preserve pressure coupling information) to grompp. We will run a 1-ns MD simulation. We use velocity-rescaling temperature coupling as thermostat and stochastic cell rescaling as barostat. A full explanation of the available thermostats and barostats in GROMACS can be found in the manual (see [here](http://manual.gromacs.org/documentation/current/reference-manual/algorithms/molecular-dynamics.html#temperature-coupling) for thermostat and [here](http://manual.gromacs.org/documentation/current/reference-manual/algorithms/molecular-dynamics.html#pressure-coupling) for barostat)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!cat input/md-charmm.mdp"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "f0ff0a16-ecdd-40e6-af2c-4234793043c1"
    }
   },
   "source": [
    "Note we have explictly add a section that controls the output frequency in log file (.log), energy file (.edr), in the trajcotry file (.trr) and the compress trajectory file (.xtc).\n",
    "\n",
    "gmx grompp will print an estimate for generated data and PME load. PME load will dictate how many processors should be dedicated to the PME calculation, and how many for the PP (everything except for PME) calculations. Refer to the [manual](http://manual.gromacs.org/documentation/current/user-guide/mdrun-performance.html#parallelization-schemes) for details."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "9749ba51-ceef-4d26-a92b-f056a3a4e4c1"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!gmx grompp -f input/md-charmm.mdp -c npt.gro -t npt.cpt -p topol.top -o md.tpr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "94034110-7553-4031-ab62-01022bce77b8"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!gmx mdrun -ntmpi 1 -v -deffnm md"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "247e14a4-0892-4f32-9624-8402d0b7e070"
    }
   },
   "source": [
    "As before, this run will take some time - probably more than planned for going through this tutorial. As an alternative, use the data provided here"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "cbf6faf8-a98c-464d-8e0f-aa2fd6ae36cb"
    }
   },
   "outputs": [],
   "source": [
    "##ONLY execute the lines below if you do not want to run and wait for the simulation to finish\n",
    "#!cp reference/md_charmm.log md.log\n",
    "#!cp reference/md_charmm.edr md.edr\n",
    "#!cp reference/md_charmm.gro md.gro\n",
    "#!cp reference/md_charmm.xtc md.xtc"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "f5ecb43b-4d2f-44e7-85dd-62f9d2665a17"
    }
   },
   "source": [
    "# Analysis"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "ef9d62ee-3df6-4b4e-ba99-0eb1e6374fb2"
    }
   },
   "source": [
    "Now that we have simulated our protein, we should run some analysis on the system. What types of data are important? This is an important question to ask before running the simulation, so you should have some ideas about the types of data you will want to collect in your own systems. For this tutorial, a few basic tools will be introduced."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "ef9d62ee-3df6-4b4e-ba99-0eb1e6374fb2"
    }
   },
   "source": [
    "The first tool is trjconv, which is used as a post-processing tool to strip out coordinates, correct for periodicity, or manually alter the trajectory (time units, frame frequency, etc). Here you find a suggested workflow for trjconv [link](https://manual.gromacs.org/2021/user-guide/terminology.html?highlight=periodic%20boundary). This exercise, we will use trjconv to account for any periodicity in the system. The protein will diffuse through the unit cell, and may appear \"broken\" or may \"jump\" across to the other side of the box. To account for such actions, issue the following:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "49e846cb-4d93-4ff7-972e-2a01e68ffe13"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!printf \"1\\n1\\n\" | gmx trjconv -s md.tpr -f md.xtc -o md_center.xtc -center -pbc mol"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "232962b5-46c5-460e-a6cd-d2c59ae98683"
    }
   },
   "source": [
    "Select 1 (\"Protein\") as the group to be centered and 1 (\"Protein\") for output. We will conduct all our analyses on this \"corrected\" trajectory. Let's look at so obtained trajcetory using vmd. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "f45c2308-0e74-4025-ac1e-200ba2869162"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "import nglview as ng \n",
    "import mdtraj as md\n",
    "traj = md.load(\"md_center.xtc\", top=\"1fjs_newbox.gro\")\n",
    "view = ng.show_mdtraj(traj)\n",
    "view"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In alternative, remove the comment character (#) to use VMD "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "f45c2308-0e74-4025-ac1e-200ba2869162"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "#!vmd 1fjs_newbox.gro md_center.xtc"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "ef9d62ee-3df6-4b4e-ba99-0eb1e6374fb2"
    }
   },
   "source": [
    "Note, the protein should never interact with its periodic image (minimum image convention), otherwise the forces calculated will be spurious. To calculate the distance between the protein and its periodic image, we use the tool mindist with the option -pi. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "49e846cb-4d93-4ff7-972e-2a01e68ffe13"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!printf \"1\\n\" | gmx mindist -s md.tpr -f md_center.xtc -pi -od mindist.xvg \n",
    "#!xmgrace mindist.xvg"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The distance between the protein and its periodic image should not be smaller than the cut-off used to describe non-bonded interactions."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "232962b5-46c5-460e-a6cd-d2c59ae98683"
    }
   },
   "source": [
    "Now let's look at structural stability. GROMACS has a built-in utility for RMSD calculations called rms. To calculate RMSD relative to the crystal structure, issue this command:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "41a754a7-38be-4f22-b1af-838fefef505b"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!printf \"4\\n1\\n\" | gmx rms -s em.tpr -f md_center.xtc -o rmsd_xray.xvg -tu ns -xvg none"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "ca9b922f-429b-45f5-b118-aa633c85c2e6"
    }
   },
   "source": [
    "Choose 4 (\"Backbone\") for both the least-squares fit and the group for RMSD calculation. The -tu flag will output the results in terms of ns, even though the trajectory was written in ps. This is done for clarity of the output (especially if you have a long simulation - 1ns does not look as nice as 100 ns). The output plot will show the RMSD relative to the structure present in the original pdb file:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "4ce04079-a188-4372-ac3f-10665cd8b1a5"
    },
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "df = pd.read_csv('rmsd_xray.xvg', sep='\\s+', header=None, names=['time','RMSD'])\n",
    "df.plot('time')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Or for alterantive visualization, remove the comment characters (#) in the following cells:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "41a754a7-38be-4f22-b1af-838fefef505b"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "#!printf \"4\\n1\\n\" | gmx rms -s em.tpr -f md_center.xtc -o rmsd_xray.xvg -tu ns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "0938839f-aaff-455f-a2e0-8e6e1c5f7e19"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "#!xmgrace rmsd_xray.xvg "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "e09ab1d9-4a3c-4f31-a309-524cafbea23f"
    }
   },
   "source": [
    "The time serie shows the RMSD levels off to ~0.15 nm (1 Å), indicating that the structure is stable. \n",
    "\n",
    "The option `-h` provides help information for GROMACS tool. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!gmx rms -h"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "0c6ed6c2-b327-4aa5-be30-5a34dda3fb00"
    }
   },
   "source": [
    "## Radius of gyration"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "5e00cc55-3f22-419c-b7ec-12b1a1974c87"
    }
   },
   "source": [
    "The radius of gyration of a protein is a measure of its compactness. If a protein is stably folded, it will likely maintain a relatively steady value of Rg. If a protein unfolds, its Rg will change over time. Let's analyze the radius of gyration for the protein in our simulation:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "d5801034-d329-48bd-9563-b59b3df88421"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!echo \"1\" | gmx gyrate -f md_center.xtc -s md.tpr -o gyrate.xvg -xvg none"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "4ce04079-a188-4372-ac3f-10665cd8b1a5"
    },
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "df = pd.read_csv('gyrate.xvg', sep='\\s+', header=None, names=['time','Rg'], usecols=[0, 1])\n",
    "df.plot('time')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Or for alterantive visualization, remove the comment characters (#) in the following cells:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "d5801034-d329-48bd-9563-b59b3df88421"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "#!echo \"1\" | gmx gyrate -f md_center.xtc -s md.tpr -o gyrate.xvg "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "bacba8b7-de93-4e5f-a08b-5154ace5af43"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "#!xmgrace gyrate.xvg"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "ca31ca31-edde-434e-9757-96e683450f2b"
    }
   },
   "source": [
    "We can see from the reasonably invariant Rg values that the protein remains very stable, in its compact (folded) form over the course of 1 ns at 300 K. This result is not unexpected, but illustrates an advanced capacity of GROMACS analysis that comes built-in."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "0c6ed6c2-b327-4aa5-be30-5a34dda3fb00"
    }
   },
   "source": [
    "## Index file"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Index groups are necessary for almost every GROMACS tools. All GROMACS tools can generate default index groups. If one needs special index groups, he/she can use gmx make_ndx to generate an index file (ndx). For example the command `splitch 1` splits the group 1 (Protein) in chains and the command `q`  close the tool.  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!printf \"splitch 1\\nq\\n\" | gmx make_ndx -f em.tpr -o "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can calculate the hydrogen bonds between the two protein chains using the tool gmx hbond. The option -num provide the number of hydrogen bond as a funtion of time.  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!printf \"19\\n20\\n\"| gmx hbond -f md.xtc -s md.tpr  -n index.ndx -num -xvg none"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "4ce04079-a188-4372-ac3f-10665cd8b1a5"
    },
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "df = pd.read_csv('hbnum.xvg', sep='\\s+', header=None, names=['time','H-bonds'], usecols=[0, 1])\n",
    "df.plot('time')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Or for alterantive visualization, remove the comment characters (#) in the following cells:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#!printf \"19\\n20\\n\"| gmx hbond -f md.xtc -s md.tpr  -n index.ndx -num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#!xmgrace hbnum.xvg"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "f71b256d-7af7-4fc5-aecf-3a7470134fb9"
    }
   },
   "source": [
    "## Excursion: Plotting gromacs data with \"pandas\" in python and notebooks"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "4c87141e-8583-497a-8c8c-22ca7e149a3f"
    }
   },
   "source": [
    "To analyse or visualize simulation data in python or jupyter notebooks, we can output a simplified xvg format from gmx-analysis tools with the option `-xvg none`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "9ebad872-0589-4675-a240-b89c396a35c1"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!echo \"12\\n0\\n\" | gmx energy -f em.edr -o potential.xvg -xvg none"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "a4591650-99ca-436f-a572-7e254adb454e"
    }
   },
   "source": [
    "And here is the plot.."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "nbpresent": {
     "id": "4ce04079-a188-4372-ac3f-10665cd8b1a5"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "df = pd.read_csv('potential.xvg', sep='\\s+', header=None, names=['time','energy'])\n",
    "df.plot('time')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.15"
  },
  "nbpresent": {
   "slides": {
    "5ee989b6-b87f-45b2-b186-0f81e2eb6c0e": {
     "id": "5ee989b6-b87f-45b2-b186-0f81e2eb6c0e",
     "prev": null,
     "regions": {
      "1099d9ed-4336-403d-8924-acb02ce1d7c0": {
       "attrs": {
        "height": 0.2,
        "width": 0.4,
        "x": 0.1,
        "y": 0.7
       },
       "id": "1099d9ed-4336-403d-8924-acb02ce1d7c0"
      },
      "159e8040-85d4-4abc-8f26-2cf90a0407d7": {
       "attrs": {
        "height": 0.6,
        "width": 0.8,
        "x": 0.1,
        "y": 0.1
       },
       "id": "159e8040-85d4-4abc-8f26-2cf90a0407d7"
      },
      "d9ecb908-45c1-485f-bb18-bbc91a1fd84e": {
       "attrs": {
        "height": 0.2,
        "width": 0.4,
        "x": 0.5,
        "y": 0.7
       },
       "id": "d9ecb908-45c1-485f-bb18-bbc91a1fd84e"
      }
     }
    }
   },
   "themes": {}
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
